package cn.yx.common.core.util.date;

import cn.yx.common.core.enums.date.DatePatternEnum;

import java.sql.Timestamp;
import java.time.*;
import java.util.Calendar;
import java.util.Date;

/**
 * <p>日期时间工具类</p>
 * <p>建议使用JDK1.8提供的新时间API，如Instant, LocalDate, LocalDateTime类等</p>
 *
 * @author Wgssmart
 */
public final class DateUtil {

    private DateUtil() {
    }

    /**
     * 获取系统当前时间毫秒值
     *
     * @return 系统当前时间毫秒值
     */
    public static long millis() {
        return Instant.now().toEpochMilli();
    }

    /**
     * 获取Date类型对应的时间毫秒值
     *
     * @param date 需要转换的Date实例
     * @return 时间毫秒值
     */
    public static long millis(Date date) {
        return date.getTime();
    }

    /**
     * 获取Calendar类型对应的时间毫秒值
     *
     * @param calendar 需要转换的Calendar实例
     * @return 时间毫秒值
     */
    @Deprecated
    public static long millis(Calendar calendar) {
        return calendar.getTimeInMillis();
    }

    /**
     * 获取Timestamp类型对应的时间毫秒值
     *
     * @param timestamp 需要转换的Timestamp实例
     * @return 时间毫秒值
     */
    public static long millis(Timestamp timestamp) {
        return timestamp.getTime();
    }

    /**
     * 获取LocalDateTime类型对应的时间毫秒值
     *
     * @param localDateTime 需要转换的LocalDateTime实例
     * @return 时间毫秒值
     */
    public static long millis(LocalDateTime localDateTime) {
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    /**
     * 获取instant类型对应的时间毫秒值
     *
     * @param instant 需要转换的instant实例
     * @return 时间毫秒值
     */
    public static long millis(Instant instant) {
        return instant.toEpochMilli();
    }

    /**
     * 获取当前时间的Date对象
     *
     * @return 当前时间的Date对象
     */
    public static Date date() {
        return Date.from(Instant.now());
    }

    /**
     * Calendar实例转换成Date实例
     *
     * @param calendar 需要转换的Calendar实例
     * @return 转换后的Date实例
     */
    @Deprecated
    public static Date date(Calendar calendar) {
        return calendar.getTime();
    }

    /**
     * Instant实例转化成Date实例
     *
     * @param instant
     * @return
     */
    public static Date date(Instant instant) {
        return Date.from(instant);
    }

    /**
     * LocalDateTime实例转化成Date实例
     *
     * @param localDateTime
     * @return
     */
    public static Date date(LocalDateTime localDateTime) {
        return Date.from(instant(localDateTime));
    }

    /**
     * LocalDate实例转化成Date实例
     *
     * @param localDate
     * @return
     */
    public static Date date(LocalDate localDate) {
        return Date.from(instant(localDate));
    }

    /**
     * 时间毫秒值转换成Date实例
     *
     * @param millis 时间毫秒值
     * @return 时间毫秒值对应的Date实例
     */
    public static Date date(long millis) {
        return Date.from(Instant.ofEpochMilli(millis));
    }

    /**
     * 获取当前时间的Instant对象
     *
     * @return
     */
    public static Instant instant() {
        return Instant.now();
    }

    /**
     * Date实例转换成Instant实例
     *
     * @param date 需要转换的Date实例
     * @return 转换后的Instant实例
     */
    public static Instant instant(Date date) {
        return date.toInstant();
    }

    /**
     * Calendar实例转换成Instant实例
     *
     * @param calendar 需要转换的Calendar实例
     * @return 转换后的Instant实例
     */
    @Deprecated
    public static Instant instant(Calendar calendar) {
        return calendar.getTime().toInstant();
    }

    /**
     * LocalDateTime实例转换成Instant实例
     *
     * @param localDateTime 需要转换的LocalDateTime实例
     * @return 转换后的Instant实例
     */
    public static Instant instant(LocalDateTime localDateTime) {
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant();
    }

    /**
     * LocalDate实例转换成Instant实例
     *
     * @param localDate 需要转换的LocalDate实例
     * @return 转换后的Instant实例
     */
    public static Instant instant(LocalDate localDate) {
        return localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
    }

    /**
     * 时间毫秒值转换成Instant实例
     *
     * @param millis 时间毫秒值
     * @return 时间毫秒值对应的Instant实例
     */
    public static Instant instant(long millis) {
        return Instant.ofEpochMilli(millis);
    }

    /**
     * Timestamp转Instant
     *
     * @param timestamp
     * @return
     */
    public static Instant instant(Timestamp timestamp) {
        return Instant.ofEpochMilli(timestamp.getTime());
    }

    /**
     * 获取当前时间的LocalDate对象
     *
     * @return
     */
    public static LocalDate localDate() {
        return LocalDate.now(ZoneId.systemDefault());
    }

    /**
     * Date实例转换成LocalDate实例
     *
     * @param date
     * @return
     */
    public static LocalDate localDate(Date date) {
        return LocalDate.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }

    /**
     * Date实例转换成LocalDate实例
     *
     * @param calendar
     * @return
     */
    @Deprecated
    public static LocalDate localDate(Calendar calendar) {
        return LocalDate.ofInstant(calendar.getTime().toInstant(), ZoneId.systemDefault());
    }

    /**
     * 获取当前时间的LocalDateTime对象
     *
     * @return
     */
    public static LocalDateTime localDateTime() {
        return LocalDateTime.now(ZoneId.systemDefault());
    }

    /**
     * Date实例转换成LocalDateTime实例
     *
     * @param date 需要转换的Date实例
     * @return 转换后的LocalDateTime实例
     */
    public static LocalDateTime localDateTime(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }

    /**
     * Calendar实例转换成LocalDateTime实例
     *
     * @param calendar 需要转换的Calendar实例
     * @return 转换后的LocalDateTime实例
     */
    @Deprecated
    public static LocalDateTime localDateTime(Calendar calendar) {
        return LocalDateTime.ofInstant(calendar.getTime().toInstant(), ZoneId.systemDefault());
    }

    /**
     * 时间毫秒值转换成LocalDateTime实例
     *
     * @param millis 时间毫秒值
     * @return 时间毫秒值对应的LocalDateTime实例
     */
    public static LocalDateTime localDateTime(long millis) {
        return LocalDateTime.ofInstant(instant(millis), ZoneId.systemDefault());
    }

    /**
     * Instant实例转换成LocalDateTime实例
     *
     * @param instant 需要转换的Instant实例
     * @return 转换后的LocalDateTime实例
     */
    public static LocalDateTime localDateTime(Instant instant) {
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    }

    /**
     * Timestamp转LocalDateTime
     *
     * @param timestamp
     * @return
     */
    public static LocalDateTime localDateTime(Timestamp timestamp) {
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp.getTime()), ZoneId.systemDefault());
    }

    /**
     * 获取当前时间的LocalTime对象
     *
     * @return
     */
    public static LocalTime localTime() {
        return LocalTime.now(ZoneId.systemDefault());
    }

    /**
     * 获取当前时间的Calendar
     *
     * @return
     */
    @Deprecated
    public static Calendar calendar() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(millis());
        return calendar;
    }

    /**
     * Date类型转换成Calendar
     *
     * @param date 需要转换的Date实例
     * @return 转换后的Calendar实例
     */
    @Deprecated
    public static Calendar calendar(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar;
    }

    /**
     * 时间毫秒值转换成Calendar实例
     *
     * @param millis 时间毫秒值
     * @return 时间毫秒值对应的Calendar实例
     */
    @Deprecated
    public static Calendar calender(long millis) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(millis);
        return calendar;
    }

    /**
     * 获取当前日期的字符串
     *
     * @return
     */
    public static String dateStr() {
        return DateFormatUtil.format(Instant.now(), DatePatternEnum.DATE.getValue());
    }

    /**
     * 获取当前日期时间的字符串
     *
     * @return
     */
    public static String datetimeStr() {
        return DateFormatUtil.format(Instant.now(), DatePatternEnum.DATETIME.getValue());
    }

}
